/**
 * 单线程和异步、事件循环、宏任务 微任务
 *
 * 当 then 返回 promise 对象时，可以认为是多出一个 promise 实例。
 */

Promise.resolve()
  .then(() => {
    console.log(0);
    return Promise.resolve(4);
  })
  .then((res) => {
    console.log(res);
  });

Promise.resolve()
  .then(() => {
    console.log(1);
  })
  .then(() => {
    console.log(2);
  })
  .then(() => {
    console.log(3);
  })
  .then(() => {
    console.log(5);
  })
  .then(() => {
    console.log(6);
  });

// 如果有多个 fulfilled 状态的 promise 实例，同时执行 then 链式调用，then 会交替调用。这是编译器的优化，防止一个 promise 持续占据事件

// 结果为1，10，100，2，20，200，3，30，300，4，40，400
Promise.resolve()
  .then(() => {
    console.log(1);
  })
  .then(() => {
    console.log(2);
  })
  .then(() => {
    console.log(3);
  })
  .then(() => {
    console.log(4);
  });

Promise.resolve()
  .then(() => {
    console.log(10);
  })
  .then(() => {
    console.log(20);
  })
  .then(() => {
    console.log(30);
  })
  .then(() => {
    console.log(40);
  });

Promise.resolve()
  .then(() => {
    console.log(100);
  })
  .then(() => {
    console.log(200);
  })
  .then(() => {
    console.log(300);
  })
  .then(() => {
    console.log(400);
  });

/**
 * then 返回 promise 实例和直接执行 `Promise.resolve()` 不一样，它需要等待两个过程
 * - promise 状态由 pending 变为 fulfilled
 * - then 函数挂载到 microTaskQueue
 * 所以，它变的会“慢两拍”。
 */

// 结果为1，10，20，30，100，40，200，300，400
Promise.resolve()
  .then(() => {
    console.log(1);
    return Promise.resolve(100); // 相当于多处一个 promise 实例，如下注释的代码
  })
  .then((res) => {
    console.log(res);
  })
  .then(() => {
    console.log(200);
  })
  .then(() => {
    console.log(300);
  })
  .then(() => {
    console.log(400);
  });

Promise.resolve()
  .then(() => {
    console.log(10);
  })
  .then(() => {
    console.log(20);
  })
  .then(() => {
    console.log(30);
  })
  .then(() => {
    console.log(40);
  });

// 上面的代码可以理解为下边这种

Promise.resolve().then(() => {
  console.log(1);
});

Promise.resolve()
  .then(() => {
    console.log(10);
  })
  .then(() => {
    console.log(20);
  })
  .then(() => {
    console.log(30);
  })
  .then(() => {
    console.log(40);
  });

Promise.resolve().then(() => {
  // 第一拍
  const p = Promise.resolve(100);
  Promise.resolve().then(() => {
    // 第二拍
    p.then((res) => {
      console.log(res);
    })
      .then(() => {
        console.log(200);
      })
      .then(() => {
        console.log(300);
      })
      .then(() => {
        console.log(400);
      });
  });
});
